#include "SHA256.h"
#include <openssl/evp.h>  // 引入新的EVP接口
#include <openssl/err.h>  // 用于错误处理
#include <sstream>
#include <iomanip>
#include <cstring>

std::string sha256(const std::string& input) {
    // 1. 创建哈希上下文（OpenSSL 3.0推荐的新方式）
    EVP_MD_CTX* ctx = EVP_MD_CTX_new();
    if (ctx == nullptr) {
        return "";  // 上下文创建失败
    }

    // 2. 初始化哈希计算（指定使用SHA256算法）
    // EVP_sha256()返回SHA256算法的描述结构，兼容新旧版本
    if (EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr) != 1) {
        EVP_MD_CTX_free(ctx);  // 释放资源
        return "";  // 初始化失败
    }

    // 3. 传入数据更新哈希（支持分块传入，这里一次性传入）
    if (EVP_DigestUpdate(ctx, input.c_str(), input.size()) != 1) {
        EVP_MD_CTX_free(ctx);
        return "";  // 更新失败
    }

    // 4. 完成哈希计算，获取结果
    unsigned char hash[EVP_MAX_MD_SIZE];  // 足够存储任何哈希算法的结果
    unsigned int hash_len;  // 实际哈希长度（SHA256固定为32字节）
    if (EVP_DigestFinal_ex(ctx, hash, &hash_len) != 1) {
        EVP_MD_CTX_free(ctx);
        return "";  // 计算失败
    }

    // 5. 释放上下文资源（必须调用，避免内存泄漏）
    EVP_MD_CTX_free(ctx);

    // 6. 将哈希值（二进制）转换为十六进制字符串（与原代码逻辑一致）
    std::stringstream ss;
    for (unsigned int i = 0; i < hash_len; ++i) {
        ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(hash[i]);
    }

    return ss.str();
}
